﻿using System.Data;
using System.Security.Claims;
using Devonline.Communication.Messages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;

namespace Devonline.Identity.Admin.Controllers;

/// <summary>
/// 用户管理
/// </summary>    
[Route("api/[controller]")]
[ApiController]
[SecurityHeaders]
[Authorize(Roles = GROUP_MAINTAINERS)]
public class UsersController : ControllerBase
{
    private readonly AdminSetting _appSetting;
    private readonly UserManager<User> _userManager;
    private readonly RoleManager<Role> _roleManager;
    private readonly UserStore _userStore;
    private readonly AuthorizationService _authorizationService;
    private readonly IDataWithAttachmentService<User> _dataService;
    private readonly ILogger<UsersController> _logger;
    private readonly IDataProtectionProvider _protector;
    private readonly IMessageCommunicator _communicator;
    private static CancellationToken CancellationToken => CancellationToken.None;

    public UsersController(
        AdminSetting appSetting,
        UserManager<User> userManager,
        RoleManager<Role> roleManager,
        UserStore userStore,
        AuthorizationService authorizationService,
        IDataWithAttachmentService<User> dataService,
        IDataProtectionProvider provider,
        IMessageCommunicator communicator,
        ILogger<UsersController> logger
        )
    {
        _appSetting = appSetting;
        _userManager = userManager;
        _roleManager = roleManager;
        _userStore = userStore;
        _authorizationService = authorizationService;
        _dataService = dataService;
        _logger = logger;
        _protector = provider;
        _communicator = communicator;
        _userManager.Logger = _logger;
    }

    #region 基础操作
    /// <summary>
    /// get user for filter
    /// </summary>
    /// <returns></returns>
    [HttpGet, EnableQuery]
    public IActionResult Get()
    {
        _logger.LogInformation("user {user} query the user list", _dataService.UserName);
        var select = Request.GetRequestOption<string>(QUERY_OPTION_SELECT);
        if (string.IsNullOrWhiteSpace(select) || select == CHAR_STAR.ToString() || select.Contains(nameof(Identity.User.PasswordHash), StringComparison.InvariantCultureIgnoreCase))
        {
            return BadRequest("不可查询用户敏感数据!");
        }

        return Ok(_dataService.GetQueryable());
    }
    /// <summary>
    /// 新增用户
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost]
    public async Task<IActionResult> CreateAsync(UserViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(_appSetting.DefaultPassword))
        {
            return BadRequest("用户名和默认密码不可为空!");
        }

        _logger.LogInformation($"user {_dataService.UserName} will add the user {viewModel.ToJsonString()}");

        var user = await _userManager.FindByNameAsync(viewModel.UserName);
        if (user != null)
        {
            return BadRequest($"用户名 {viewModel.UserName} 已经存在!");
        }

        if (GetBuildinUsers().Contains(viewModel.UserName))
        {
            return BadRequest($"不可创建内置用户 {viewModel.UserName} !");
        }

        user = new User
        {
            Name = viewModel.Name,
            UserName = viewModel.UserName,
            Email = viewModel.Email,
            PhoneNumber = viewModel.PhoneNumber,
            Alias = viewModel.Alias,
            Image = viewModel.Image,
            Type = viewModel.Type,
            GroupId = viewModel.GroupId,
            Description = viewModel.Description
        };

        user.Create(_dataService.UserName);
        user.Update(_dataService.UserName);
        if (viewModel.Attachments != null && viewModel.Attachments.Count != 0)
        {
            await _dataService.AddAttachmentsAsync(user, viewModel.Attachments);
        }

        var result = await _userManager.CreateAsync(user);
        if (result.Succeeded)
        {
            result = await _userManager.AddPasswordAsync(user, _appSetting.DefaultPassword);
            if (result.Succeeded)
            {
                _logger.LogWarning("user {user} success to add the user {targetUser} for default password", _dataService.UserName, viewModel.UserName);
            }
            else
            {
                _logger.LogWarning("user {user} success to add the user {targetUser} but no password", _dataService.UserName, viewModel.UserName);
            }

            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to add the user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 修改用户
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<IActionResult> UpdateAsync(UserViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName))
        {
            return BadRequest("用户名不可为空!");
        }

        _logger.LogInformation("user {user} will update the user {targetUser}", _dataService.UserName, viewModel);
        var user = await _userManager.FindByNameAsync(viewModel.UserName);
        if (user is null)
        {
            return BadRequest($"用户名 {viewModel.UserName} 不存在!");
        }

        //不可修改内置用户名
        if ((viewModel.UserName != user.UserName || viewModel.Type != user.Type) && GetBuildinUsers().Contains(user.Name))
        {
            return BadRequest($"用户 {viewModel.Name} 为内置用户, 不可修改用户名和用户类型!");
        }

        //不可修改用户名
        user.UserName = viewModel.UserName;
        user.Name = viewModel.Name;
        user.Email = viewModel.Email;
        user.PhoneNumber = viewModel.PhoneNumber;
        user.Alias = viewModel.Alias;
        user.Image = viewModel.Image;
        user.Type = viewModel.Type;
        user.GroupId = viewModel.GroupId;
        user.Description = viewModel.Description;

        user.Update(_dataService.UserName);
        await _dataService.UpdateAttachmentsAsync(user, viewModel.Attachments);
        var result = await _userManager.UpdateAsync(user);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to update the user {targetUser}", _dataService.UserName, viewModel.UserName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to update the user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 删除用户(逻辑删除)
    /// TBC 删除用户的时候，需要把用户的角色和权限也一起删除
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteAsync(string id)
    {
        _logger.LogInformation("user {user} will logic delete the user {targetUser}", _dataService.UserName, id);
        var user = await _userManager.FindByIdAsync(id);
        if (user is null)
        {
            return BadRequest($"用户 {id} 不存在!");
        }

        //不可删除内置用户
        if (GetBuildinUsers().Contains(user.Name))
        {
            return BadRequest($"内置用户 {user.Name} 不可删除!");
        }

        user.State = DataState.Deleted;
        var result = await _userManager.UpdateAsync(user);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to logic delete the user {targetUser}", _dataService.UserName, user.UserName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to logic delete the user {targetUser}, error message is: {errorMessage}", _dataService.UserName, user.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 新增用户的一个 Claim
    /// </summary>
    /// <param name="id"></param>
    /// <param name="claim"></param>
    /// <returns></returns>
    [HttpPost("AddClaim/{id}")]
    public async Task<ActionResult> AddClaimAsync(string id, Claim claim)
    {
        _logger.LogInformation("user {user} will add claim to user {targetUser}", _dataService.UserName, id);
        var user = await _userManager.FindByIdAsync(id);
        if (user is null)
        {
            return BadRequest($"用户 {id} 不存在!");
        }

        var result = await _userManager.AddClaimAsync(user, claim);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to add claim to user {targetUser}", _dataService.UserName, user.Name);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to add claim to user {targetUser}, error message is: {errorMessage}", _dataService.UserName, user.Name, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 移除用户的一个 Claim
    /// </summary>
    /// <param name="id"></param>
    /// <param name="claim"></param>
    /// <returns></returns>
    [HttpPost("RemoveClaim/{id}")]
    public async Task<ActionResult> RemoveClaimAsync(string id, Claim claim)
    {
        _logger.LogInformation("user {user} will remove claim to user {targetUser}", _dataService.UserName, id);
        var user = await _userManager.FindByIdAsync(id);
        if (user is null)
        {
            return BadRequest($"用户 {id} 不存在!");
        }

        var result = await _userManager.RemoveClaimAsync(user, claim);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to remove claim to user {targetUser}", _dataService.UserName, user.Name);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to remove claim to user {targetUser}, error message is: {errorMessage}", _dataService.UserName, user.Name, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    #endregion

    #region 用户敏感信息
    /// <summary>
    /// 设置用户基本信息
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost("SetUserProfile")]
    public async Task<IActionResult> SetUserProfileAsync(LevelViewModel viewModel)
    {
        var user = await _userManager.FindByIdAsync(viewModel.Id);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.Name} 不存在!");
        }

        if (viewModel.Name is not null && viewModel.Name != user.Name)
        {
            _logger.LogInformation("user {user} will set the user {targetUser} name to {name}", _dataService.UserName, user.UserName, viewModel.Name);
            await _userStore.SetNameAsync(user, viewModel.Name, CancellationToken);
        }

        if (viewModel.Alias is not null && viewModel.Alias != user.Alias)
        {
            _logger.LogInformation("user {user} will set the user {targetUser} alias to {alias}", _dataService.UserName, user.UserName, viewModel.Alias);
            await _userStore.SetAliasAsync(user, viewModel.Alias, CancellationToken);
        }

        if (viewModel.Image is not null && viewModel.Image != user.Image)
        {
            if (viewModel.Attachments is null || viewModel.Attachments.Count == 0)
            {
                return BadRequest($"用户 {user.Name} 未上传头像信息!");
            }

            _logger.LogInformation("user {user} will set the user {targetUser} image to {image}", _dataService.UserName, user.UserName, viewModel.Image);
            await _userStore.SetImageAsync(user, viewModel.Image, CancellationToken);
        }

        if (user.Type != viewModel.Type)
        {
            _logger.LogInformation("user {user} will set the user {targetUser} AuthorizeType to {type}", _dataService.UserName, user.UserName, viewModel.Type);
            await _userStore.SetAuthorizeTypeAsync(user, viewModel.Type, CancellationToken);
        }

        if (viewModel.Level is not null)
        {
            _logger.LogInformation("user {user} will set the user {targetUser} level to {level}", _dataService.UserName, user.UserName, viewModel.Level);
            await _userStore.SetLevelAsync(user, viewModel.Level, CancellationToken);
        }

        //user.Update(_dataService.UserName);
        var identityResult = await _userStore.UpdateAsync(user);
        if (identityResult.Succeeded)
        {
            _logger.LogInformation("user {user} success to set the user profile!", _dataService.UserName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        return BadRequest(identityResult.GetErrorMessage());
    }

    [HttpPost("ChangePassword")]
    public async Task<IActionResult> ChangePasswordAsync(ChangePasswordViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.Password) || string.IsNullOrWhiteSpace(viewModel.NewPassword))
        {
            return BadRequest($"用户名, 密码和新密码都不可为空!");
        }

        _logger.LogInformation("user {user} will change the password for user {targetUser}", _dataService.UserName, viewModel.UserName);
        var user = await _userManager.FindByIdAsync(viewModel.Id);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userManager.ChangePasswordAsync(user, viewModel.Password, viewModel.NewPassword);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to change the password for user {targetUser}", _dataService.UserName, viewModel.UserName);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to change the password for user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    [HttpPost("ResetPassword")]
    public async Task<IActionResult> ResetPasswordAsync(ResetPasswordViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.Password) || string.IsNullOrWhiteSpace(viewModel.Token))
        {
            return BadRequest($"用户名和密码都不可为空!");
        }

        _logger.LogInformation("user {user} will reset the password user {targetUser}", _dataService.UserName, viewModel.UserName);
        var user = await _userManager.FindByIdAsync(viewModel.Id);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userManager.ResetPasswordAsync(user, viewModel.Token, viewModel.Password);

        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to reset the password for user {targetUser}", _dataService.UserName, viewModel.UserName);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to reset the password for user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    [HttpPost("ChangePhoneNumber")]
    public async Task<IActionResult> ChangePhoneNumberAsync(ChangePhoneNumberViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.PhoneNumber) || string.IsNullOrWhiteSpace(viewModel.Token))
        {
            return BadRequest($"用户名和手机号码都不可为空!");
        }

        _logger.LogInformation("user {user} will change the phone number for user {targetUser}", _dataService.UserName, viewModel.UserName);
        var user = await _userManager.FindByIdAsync(viewModel.Id);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userManager.ChangePhoneNumberAsync(user, viewModel.PhoneNumber, viewModel.Token);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to change the phone number for user {targetUser}", _dataService.UserName, viewModel.UserName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to change the phone number for user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    [HttpPost("ChangeEmail")]
    public async Task<IActionResult> ChangeEmailAsync(ChangeEmailViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.Email) || string.IsNullOrWhiteSpace(viewModel.Token))
        {
            return BadRequest($"用户名和电子邮件地址都不可为空!");
        }

        _logger.LogInformation("user {user} will change the email for user {targetUser}", _dataService.UserName, viewModel.UserName);
        var user = await _userManager.FindByIdAsync(viewModel.Id);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userManager.ChangeEmailAsync(user, viewModel.Email, viewModel.Token);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success to change the email for user {targetUser}", _dataService.UserName, viewModel.UserName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to change the email for user {targetUser}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, errorMessage);
        }

        return BadRequest(errorMessage);
    }

    [HttpGet("GetPasswordResetToken/{userName}")]
    public async Task<IActionResult> GetPasswordResetTokenAsync(string userName)
    {
        _logger.LogInformation("user {user} will get password reset token for user {targetUser}", _dataService.UserName, userName);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is not null)
        {
            var token = await _userManager.GeneratePasswordResetTokenAsync(user);
            if (token is not null)
            {
                return Ok(token);
            }
        }

        return BadRequest($"用户 {userName} 不存在!");
    }
    [HttpGet("GetChangePhoneNumberToken/{userName}")]
    public async Task<IActionResult> GetChangePhoneNumberTokenAsync(string userName)
    {
        _logger.LogInformation("user {user} will get change phoneNumber token for user {targetUser}", _dataService.UserName, userName);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is not null && user.PhoneNumber is not null)
        {
            var token = await _userManager.GenerateChangePhoneNumberTokenAsync(user, user.PhoneNumber);
            if (token is not null)
            {
                return Ok(token);
            }
        }

        return BadRequest($"用户 {userName} 不存在, 或者手机号码为空!");
    }
    [HttpGet("GetChangeEmailToken/{userName}")]
    public async Task<IActionResult> GetChangeEmailTokenAsync(string userName)
    {
        _logger.LogInformation("user {user} will get change email token for user {targetUser}", _dataService.UserName, userName);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is not null && !string.IsNullOrWhiteSpace(user.Email))
        {
            var token = await _userManager.GenerateChangeEmailTokenAsync(user, user.Email);
            if (token is not null)
            {
                return Ok(token);
            }
        }

        return BadRequest($"用户 {userName} 不存在或电子邮件为空!");
    }
    #endregion

    #region 用户角色
    /// <summary>
    /// 获取用户角色列表
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    [HttpGet("GetUserRoles/{userName}")]
    public async Task<ActionResult> GetUserRolesAsync(string userName)
    {
        _logger.LogInformation("user {user} will query user {targetUser} roles", _dataService.UserName, userName);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is null)
        {
            return BadRequest($"用户 {userName} 不存在!");
        }

        return Ok(await _userManager.GetRolesAsync(user));
    }
    /// <summary>
    /// 获取某个角色的用户列表
    /// </summary>
    /// <param name="roleName"></param>
    /// <returns></returns>
    [HttpGet("GetRoleUsers/{roleName}")]
    public async Task<IActionResult> GetRoleUsersAsync(string roleName)
    {
        _logger.LogInformation("user {user} will query role {role} users", _dataService.UserName, roleName);
        if (!await _roleManager.RoleExistsAsync(roleName))
        {
            return BadRequest($"角色 {roleName} 不存在!");
        }

        return Ok(await _userManager.GetUsersInRoleAsync(roleName));
    }
    /// <summary>
    /// 将用户添加到角色
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost("AddUserToRole")]
    public async Task<IActionResult> AddUserToRoleAsync(UserRoleViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.RoleName))
        {
            return BadRequest($"用户名和角色名都不可为空!");
        }

        _logger.LogInformation("user {user} will assign user {targetUser} to role {role}", _dataService.UserName, viewModel.UserName, viewModel.RoleName);
        var user = await _userManager.FindByNameAsync(viewModel.UserName);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        if (!await _roleManager.RoleExistsAsync(viewModel.RoleName))
        {
            return BadRequest($"当前角色 {viewModel.RoleName} 不存在!");
        }

        var result = await _userManager.AddToRoleAsync(user, viewModel.RoleName);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success assign user {targetUser} to role {role}", _dataService.UserName, viewModel.UserName, viewModel.RoleName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail assign user {targetUser} to role {role}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, viewModel.RoleName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 从角色中移除用户(物理删除)
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost("RemoveUserFromRole")]
    public async Task<IActionResult> RemoveUserFromRoleAsync(UserRoleViewModel viewModel)
    {
        if (string.IsNullOrWhiteSpace(viewModel.UserName) || string.IsNullOrWhiteSpace(viewModel.RoleName))
        {
            return BadRequest($"用户名和角色名都不可为空!");
        }

        _logger.LogInformation("user {user} will remove user {targetUser} from role {role}", _dataService.UserName, viewModel.UserName, viewModel.RoleName);
        var user = await _userManager.FindByIdAsync(_dataService.UserId);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        if (!await _roleManager.RoleExistsAsync(viewModel.RoleName))
        {
            return BadRequest($"当前角色 {viewModel.RoleName} 不存在!");
        }

        var result = await _userManager.RemoveFromRoleAsync(user, viewModel.RoleName);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success remove user {targetUser} from role {role}", _dataService.UserName, viewModel.UserName, viewModel.RoleName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail remove user {targetUser} from role {role}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, viewModel.RoleName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 更新用户角色
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="roles"></param>
    /// <returns></returns>
    [HttpPost("ChangeUserRoles/{userName}")]
    public async Task<IActionResult> ChangeUserRolesAsync(string userName, List<string> roles)
    {
        roles ??= [];
        var roleNames = roles.ToString<string>();
        _logger.LogInformation("user {user} will assign user {targetUser} to roles {roles}", _dataService.UserName, userName, roleNames);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is null)
        {
            return BadRequest($"用户 {userName} 不存在!");
        }

        var exists = await _userManager.GetRolesAsync(user);
        var adds = roles.Except(exists);
        var removes = exists.Except(roles);

        IdentityResult result = IdentityResult.Success;
        if (removes.IsNotNullOrEmpty())
        {
            result = await _userManager.RemoveFromRolesAsync(user, removes);
        }

        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success remove user {targetUser} from roles {roles}", _dataService.UserName, userName, removes.ToString<string>());
            if (adds.IsNotNullOrEmpty())
            {
                result = await _userManager.AddToRolesAsync(user, adds);
            }

            if (result.Succeeded)
            {
                _logger.LogWarning("user {user} success assign user {targetUser} to roles {roles}", _dataService.UserName, userName, adds.ToString<string>());
                await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
                return Ok();
            }
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to change user {targetUser} roles {roles}, error message is: {errorMessage}", _dataService.UserName, userName, roleNames, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    #endregion

    #region 用户组
    /// <summary>
    /// 获取用户所在组列表, 返回组名称字符串数组
    /// </summary>
    /// <param name="userName"></param>
    /// <returns></returns>
    [HttpGet("GetUserGroups/{userName}")]
    public async Task<ActionResult> GetUserGroupsAsync(string userName)
    {
        _logger.LogInformation("user {user} will query user {targetUser} groups", _dataService.UserName, userName);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is null)
        {
            return BadRequest($"用户 {userName} 不存在!");
        }

        return Ok(await _userStore.GetUserGroupsAsync(user, CancellationToken));
    }
    /// <summary>
    /// 获取组用户列表, 返回用户列表
    /// TODO TBC 目前没有分页, 此处需要返回分页结果
    /// </summary>
    /// <param name="groupName"></param>
    /// <returns></returns>
    [HttpGet("GetGroupUsers/{groupName}")]
    public async Task<IActionResult> GetGroupUsersAsync(string groupName)
    {
        _logger.LogInformation("user {user} will query group {group} users", _dataService.UserName, groupName);
        if (!await _roleManager.RoleExistsAsync(groupName))
        {
            return BadRequest($"用户组 {groupName} 不存在!");
        }

        var users = await _userStore.GetGroupUsersAsync(groupName, CancellationToken);
        if (users.IsNotNullOrEmpty())
        {
            var result = users.Select(x => new UserIdentityViewModel
            {
                Id = x.Id,
                UserName = x.UserName,
                Alias = x.Alias,
                Description = x.Description,
                Email = x.Email,
                Image = x.Image,
                Name = x.Name,
                PhoneNumber = x.PhoneNumber,
                State = x.State
            }).ToList();

            return Ok(new PagedResult { Data = result });
        }

        return Ok();
    }
    /// <summary>
    /// 将用户添加到组
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost("AddUserToGroup")]
    public async Task<IActionResult> AddUserToGroupAsync(UserGroupViewModel viewModel)
    {
        _logger.LogInformation("user {user} will assign user {targetUser} to group {group}", _dataService.UserName, viewModel.UserName, viewModel.GroupName);
        if (viewModel.GroupName is null)
        {
            return BadRequest($"组织单位 {viewModel.GroupName} 不能为空!");
        }

        var user = await _userManager.FindByIdAsync(_dataService.UserId);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userStore.AddToGroupAsync(user, viewModel.GroupName, CancellationToken);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success assign user {targetUser} to group {group}", _dataService.UserName, viewModel.UserName, viewModel.GroupName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail assign user {targetUser} to group {group}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, viewModel.GroupName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 从组中移除用户(物理删除)
    /// </summary>
    /// <param name="viewModel"></param>
    /// <returns></returns>
    [HttpPost("RemoveUserFromGroup")]
    public async Task<IActionResult> RemoveUserFromGroupAsync(UserGroupViewModel viewModel)
    {
        _logger.LogInformation("user {user} will remove user {targetUser} from group {group}", _dataService.UserName, viewModel.UserName, viewModel.GroupName);
        if (viewModel.GroupName is null)
        {
            return BadRequest($"组织单位 {viewModel.GroupName} 不能为空!");
        }

        var user = await _userManager.FindByIdAsync(_dataService.UserId);
        if (user is null)
        {
            return BadRequest($"用户 {viewModel.UserName} 不存在!");
        }

        var result = await _userStore.RemoveFromGroupAsync(user, viewModel.GroupName, CancellationToken);
        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success remove user {targetUser} from group {group}", _dataService.UserName, viewModel.UserName, viewModel.GroupName);
            await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
            return Ok();
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail remove user {targetUser} from group {group}, error message is: {errorMessage}", _dataService.UserName, viewModel.UserName, viewModel.GroupName, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    /// <summary>
    /// 更新用户组织单位
    /// </summary>
    /// <param name="userName"></param>
    /// <param name="groups"></param>
    /// <returns></returns>
    [HttpPost("ChangeUserGroups/{userName}")]
    public async Task<IActionResult> ChangeUserGroupsAsync(string userName, List<string> groups)
    {
        groups ??= [];
        var groupNames = groups.ToString<string>();
        _logger.LogInformation("user {user} will assign user {targetUser} to groups {groups}", _dataService.UserName, userName, groupNames);
        var user = await _userManager.FindByNameAsync(userName);
        if (user is null)
        {
            return BadRequest($"用户 {userName} 不存在!");
        }

        var exists = await _userStore.GetUserGroupsAsync(user);
        var adds = groups.Except(exists);
        var removes = exists.Except(groups);

        var result = IdentityResult.Success;
        if (removes.IsNotNullOrEmpty())
        {
            result = await _userStore.RemoveFromGroupsAsync(user, removes);
        }

        if (result.Succeeded)
        {
            _logger.LogWarning("user {user} success remove user {targetUser} from groups {groups}", _dataService.UserName, userName, removes.ToString<string>());
            if (adds.IsNotNullOrEmpty())
            {
                result = await _userStore.AddToGroupsAsync(user, adds);
            }

            if (result.Succeeded)
            {
                _logger.LogWarning("user {user} success assign user {targetUser} to groups {groups}", _dataService.UserName, userName, adds.ToString<string>());
                await _authorizationService.RefreshUserInfoAsync(_communicator, IdentityType.User, user.Id);
                return Ok();
            }
        }

        var errorMessage = string.Empty;
        if (result.Errors.IsNotNullOrEmpty())
        {
            errorMessage = result.Errors.Select(x => $"{x.Code}: {x.Description}").ToString<string>();
            _logger.LogWarning("user {user} fail to change user {targetUser} groups {groups}, error message is: {errorMessage}", _dataService.UserName, userName, groupNames, errorMessage);
        }

        return BadRequest(errorMessage);
    }
    #endregion

    #region 内部方法
    /// <summary>
    /// 获取内置用户
    /// </summary>
    /// <returns></returns>
    private string[] GetBuildinUsers()
    {
        var results = BUILDIN_USERS.Split(CHAR_COMMA, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
        var users = _appSetting.BuiltInUsers.Split(CHAR_COMMA, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
        return results.Concat(users).Distinct().ToArray();
    }
    #endregion
}